use std::path::PathBuf;

use config::Config;
use serde::Deserialize;
use thiserror::Error;

#[derive(Debug, Deserialize, Clone)]
pub struct FrameworkConfig {
    pub max_concurrent_tasks: usize,
    pub lua_memory_limit: usize,
    pub worker_threads: usize,
    pub enable_cross_platform_compat: bool,
    pub supported_languages: Vec<String>,
}

#[derive(Error, Debug)]
pub enum ConfigError {
    #[error("Failed to load config: {0}")]
    LoadError(String),
    #[error("Invalid configuration: {0}")]
    ValidationError(String),
}

pub fn load_config(path: Option<PathBuf>) -> Result<FrameworkConfig, ConfigError> {
    let config_builder = Config::builder();

    let config_builder = if let Some(path) = path {
        config_builder.add_source(config::File::from(path))
    } else {
        // 默认配置文件路径
        let default_path = PathBuf::from("config/prod.toml");
        if default_path.exists() {
            config_builder.add_source(config::File::from(default_path))
        } else {
            // 如果没有配置文件，则使用默认值
            config_builder
                .set_default("max_concurrent_tasks", 100)?
                .set_default("lua_memory_limit", 67108864)?
                .set_default("worker_threads", 0)?
                .set_default("enable_cross_platform_compat", true)?
                .set_default("supported_languages", vec!["javascript"])?
        }
    };

    let config = config_builder.build()?.try_deserialize()?;

    // 如果worker_threads为0，则设置为逻辑核心数的两倍
    let mut config: FrameworkConfig = config;
    if config.worker_threads == 0 {
        config.worker_threads = num_cpus::get() * 2;
    }

    // 验证配置
    if config.supported_languages.is_empty() {
        return Err(ConfigError::ValidationError(
            "At least one supported language must be specified".to_string(),
        ));
    }

    Ok(config)
}
